<template>
  <!-- 创建活动报名信息及订单 -->
  <page-meta :page-style="'overflow:' + (getPageScrollState ? 'hidden' : 'visible')"></page-meta>
  <PageContainer>
    <view class="container">
      <Header
        title="确认报名"
        :background-color="backgroundColor"
        :is-box-shadow="false"
        title-color="#fff"
      />
      <!-- 活动 + 票 信息 -->
      <InfoContainer
        :model-value="purchaseQuantity"
        v-model:is-open="isOpen"
        :activity-info="activityInfo"
        :ticket-detail="ticketDetail"
        :background-color="backgroundColor"
      />

      <HiddenBlock
        v-if="ticketDetail"
        v-model:height="hiddenBlockHeight"
        :is-opacity="isOpen"
        :background-color="backgroundColor"
        :introduction="ticketDetail?.introduction"
        :purchase-time-des="getPurchaseTimeDes(ticketDetail)"
        :refund-time-des="getRefundTimeDes(ticketDetail)"
        :review-status="ticketDetail.reviewStatus"
      />

      <!-- 表单模块 -->
      <view class="form-container" :style="{ marginTop: isOpen ? hiddenBlockHeight + 'px' : 0 }">
        <view class="px-16 pt-16 pb-8">
          <view class="text-color mb-6 disFlxJS">
            <text class="fz-16 fw-700">报名信息收集</text>
            <view
              v-if="routingParameters?.routerScene !== 'signIn'"
              class="fz-14 br-18 px-16 disFlxAC py-8"
              :style="{ color: backgroundColor, border: `1px solid ${backgroundColor}` }"
              @click="handleShowAddSheet"
            >
              <text class="ali-icon mr-4 fz-16">&#xe6ba;</text>
              <text>添加报名者</text>
            </view>
          </view>
          <!-- <view>
            <text class="fz-12 text-color">请完整填写{{ purchaseQuantity }}位报名者信息</text>
          </view> -->
          <view v-if="ticketDetail?.buyLimit === TicketBuyLimitEnum.LIMIT" class="fz-12 text-color">
            <text>报名者最多{{ ticketDetail?.buyMaxNum }}位</text>
          </view>
        </view>
        <PersonnelInfoList
          ref="personnelInfoListRef"
          :activity-id="activityInfo?.id"
          v-model:purchase-quantity="purchaseQuantity"
          :buy-min-num="ticketDetail?.buyMinNum"
        />
      </view>
    </view>
    <!-- 提交按钮 -->
    <SubmitModule
      v-model:visible="priceDetailVisible"
      :ticket-detail="ticketDetail"
      :purchase-quantity="purchaseQuantity"
      @submit="handleSubmit"
    />

    <SelectMembers
      v-if="activityInfo?.id && currentCocId"
      v-model:visible="selectMembersVisible"
      :activity-id="activityInfo.id"
      @submit="handleSelectMembersSubmit"
    />
    <ActionSheet v-model="actionSheetVisible" :item-list="itemList" @change="handleAddPerson" />

    <UniPopup ref="delayPopupRef" type="center" :isMaskClick="false" :zIndex="999">
      <view class="delay-popup br-16 disFlxCC">
        <view class="default-color fz-16 mb-12">报名信息生成中…</view>
        <view class="default-color fz-14 mb-16">系统正在生成报名信息，请耐心等待</view>
        <view class="fz-32" style="color: #2878ff">{{ delayNum }}</view>
      </view>
    </UniPopup>
  </PageContainer>
</template>

<script lang="ts" setup>
  /* createActivityRegisterOrder 确认报名 */
  import Header from '@/components/Header/index.vue';
  import PageContainer from '@/components/PageContainer/index.vue';
  import { onLoad, reLaunch } from '@/router';
  import type { CreateActivityRegisterOrder, SelectTicketType } from '@/router/types/modules';
  import { computed, ref } from 'vue';
  import { onPageScroll, onUnload } from '@dcloudio/uni-app';
  import PersonnelInfoList from './components/PersonnelInfoList.vue';
  import { type PersonnelInfoListRef, type TabItem } from './components/types';
  import { useUserStoreWithOut } from '@/store/modules/user';
  import { buildUUID } from '@/utils/uuid';
  import SelectMembers from './components/SelectMembers.vue';
  import HiddenBlock from './components/HiddenBlock.vue';
  import InfoContainer from './components/InfoContainer.vue';
  import SubmitModule from './components/SubmitModule.vue';
  import ActionSheet, { type ActionSheetItem } from '@/components/ActionSheet/index.vue';
  import type {
    ActivityCreateSuborderData,
    IActivityListResData,
    IActivityTicketResult,
    IAppRegistrationRes,
  } from '@/api/activity/types';
  import {
    activityCreateSuborder,
    activityCreateorder,
    activityticketDetail,
    getHoldRegisterInfo,
    setHoldRegisterInfo,
  } from '@/api/activity';
  import { getPurchaseTimeDes, getRefundTimeDes } from '../components/activity';
  import { isArray } from 'lodash-es';
  import { requestPayment } from '../utils/payment';
  import { isJSON, isNullOrUnDef } from '@/utils/is';
  import { TicketBuyLimitEnum } from '@/enums/activityStatusEnum';
  import { useActivityStore } from '@/store/modules/activity';
  import UniPopup from '@/uni_modules/uni-popup/components/uni-popup/uni-popup.vue';

  const routingParameters = ref<CreateActivityRegisterOrder>();
  const { getActivityOrderRouteParams } = useActivityStore();
  const backgroundColor = ref('#2878ff');
  const { userInfo, currentCocId } = useUserStoreWithOut();

  const activityInfo = ref<IActivityListResData>();
  const isOpen = ref(false);
  const purchaseQuantity = ref<number>(1);
  const ticketDetail = ref<IActivityTicketResult>();

  const personnelInfoListRef = ref<PersonnelInfoListRef | null>(null);
  function addPerson(data: TabItem) {
    personnelInfoListRef.value?.addPerson(data);
  }

  const hiddenBlockHeight = ref<number>();

  const delayPopupRef = ref<UniPopupRef>();
  const delayNum = ref(3);
  const delayTimer = ref()
  function delayStart(orderCode: string) {
    delayTimer.value = setInterval(() => {
      delayNum.value -= 1;
      if (delayNum.value === 0) {
        handlePaySuccess(orderCode)
        clearInterval(delayTimer.value);
      }
    }, 1000);
  }

  onLoad<'createActivityRegisterOrder'>(async (op) => {
    activityInfo.value = getActivityOrderRouteParams!;

    routingParameters.value = op;
    getTicketDetailData(op.ticketId);
    const holdInfo = await getHoldRegisterInfo(activityInfo.value!.id);
    const dataJson = isJSON(holdInfo);
    if (dataJson) {
      personnelInfoListRef.value?.setHoldInfo(dataJson as TabItem[]);
      return;
    }

    if (!op.selfIsSignUp) {
      addPerson({
        id: buildUUID(),
        name: userInfo.name,
        formInfo: {
          personName: userInfo.name,
          personTel: userInfo.phonenumber,
          companyName: userInfo.companyName,
          companyPosition: userInfo.companyPosition,
        },
      });
    } else if (op.routerScene === 'signIn') {
      addPerson({
        id: buildUUID(),
        name: '',
      });
    }
  });

  async function getTicketDetailData(ticketId?: number) {
    const res = await activityticketDetail((ticketId || ticketDetail.value?.id) as number);
    ticketDetail.value = res;
  }

  uni.setNavigationBarColor({
    frontColor: '#ffffff',
    backgroundColor: '#ffffff',
    animation: {
      duration: 200,
      timingFunc: 'linear',
    },
  });

  const itemList = ref<ActionSheetItem[]>([]);
  if (currentCocId) {
    itemList.value.push({
      text: '为成员报名',
      des: '（使用成员信息快速填写）',
    });
  }
  itemList.value.push({
    text: '为其他人报名',
    des: '（创建空白表单填写）',
  });

  const priceDetailVisible = ref(false);
  const actionSheetVisible = ref(false);
  const selectMembersVisible = ref(false);
  function handleAddPerson(tapIndex: number) {
    if (!currentCocId) tapIndex = 1;
    switch (tapIndex) {
      case 0:
        /** 去选择成员 */
        selectMembersVisible.value = true;
        break;
      case 1:
        /** 添加空白报名信息 */
        addPerson({
          id: buildUUID(),
          name: '',
        });
        break;
    }
  }

  function handleShowAddSheet() {
    const personNum = personnelInfoListRef.value?.getPersonNum() || 0;
    if (
      ticketDetail.value?.buyLimit === TicketBuyLimitEnum.LIMIT &&
      personNum >= ticketDetail.value?.buyMaxNum
    ) {
      uni.showModal({
        title: '提示',
        content: `最多报名${ticketDetail.value?.buyMaxNum}位`,
        showCancel: false,
      });
      return;
    }

    if (currentCocId) {
      actionSheetVisible.value = true;
    } else {
      /** 添加空白报名信息 */
      addPerson({
        id: buildUUID(),
        name: '',
      });
    }
  }

  function handleSelectMembersSubmit(list: IAppRegistrationRes[]) {
    list.forEach((v) => {
      addPerson({
        id: buildUUID(),
        name: v.userName,
        formInfo: {
          personName: v.userName,
          personTel: v.phonenumber,
          companyName: v.companyName,
          companyPosition: v.companyPosition,
        },
      });
    });
  }

  async function handleSubmit() {
    if (!ticketDetail.value || !activityInfo.value) {
      return;
    }
    const values = (await personnelInfoListRef.value?.getFieldsValue()) || [];
    const activityFormDtoList: ActivityCreateSuborderData['activityFormDtoList'] = [];
    const applicantInfo: { phone: string; name: string }[] = [];

    for (let index = 0; index < values.length; index++) {
      const val = values[index];
      const answerList: { formItemId: number; content: string[] }[] = [];
      let obj = {
        name: val[0],
        phone: val[-1],
      };

      const infoItem = applicantInfo.find((v) => v.phone === obj.phone);
      if (infoItem) {
        uni.showModal({
          title: '提示',
          content: `${obj.name}与${infoItem.name}手机号码重复`,
          showCancel: false,
        });
        return;
      }

      applicantInfo.push(obj);
      for (const key in val) {
        let content = val[key] || '';
        if (!isArray(content)) content = content.toString().split(',');
        answerList.push({
          formItemId: Number(key),
          content,
        });
      }

      activityFormDtoList.push({
        customFormItem: {
          answerList,
        },
      });
    }

    const data: ActivityCreateSuborderData = {
      activityTicketId: ticketDetail.value.id,
      activityUnionId: activityInfo.value.id,
      registerType: 'mini',
      num: purchaseQuantity.value,
      activityFormDtoList,
      shareKey: routingParameters.value?.shareKey,
      submitDiscountPrice: isNullOrUnDef(ticketDetail.value.discountPrice)
        ? ticketDetail.value.price
        : ticketDetail.value.discountPrice,
    };

    try {
      const { id } = await activityCreateSuborder(data);
      const { payCode, orderCode, payMoney } = await activityCreateorder(id);
      if (payMoney === 0 && orderCode) {
        handlePaySuccess(orderCode);
        return Promise.resolve(true);
      }
      requestPayment(payCode)
        .then(() => {
          handlePaySuccess(orderCode);
        })
        .catch(() => {
          uni.showLoading({
            title: '加载中',
            mask: true,
          });
          setTimeout(() => {
            uni.hideLoading();
            reLaunch({
              name: 'activityRegisterOrder',
              options: {
                orderCode,
                scene: 'createActivityRegisterOrder',
              },
            });
          }, 2000);
        });
    } catch (error) {
      getTicketDetailData();
    }
  }

  function handlePaySuccess(orderCode: string) {
    setHoldRegisterInfo(activityInfo.value?.id as number, '');
    personnelInfoListRef.value?.clearHoldInfo();
    if (delayNum.value) {
      delayPopupRef.value?.open();
      delayStart(orderCode);
      return
    }
    reLaunch({
      name: 'activityResult',
      options: {
        orderCode,
        equipmentNumber: routingParameters.value?.equipmentNumber,
      },
    });
  }

  const getPageScrollState = computed(
    () => priceDetailVisible.value || actionSheetVisible.value || selectMembersVisible.value,
  );

  onPageScroll(() => {});

  onUnload(() => {
    clearInterval(delayTimer.value)
  })
</script>

<style lang="scss" scoped>
  .container {
    width: 100vw;
    overflow: hidden;
    min-height: 100vh;
    background-color: #fff;
  }

  .form-container {
    background-color: #fff;
    min-height: 800rpx;
    border-radius: 32rpx 32rpx 0px 0px;
    transition: 0.5s;
    position: relative;
  }

  .text-color {
    color: #333;
  }

  .delay-popup {
    background-color: #fff;
    width: 622rpx;
    height: 320rpx;
  }
</style>
